/*
 * Galaxium Messenger
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2007 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

using Gtk;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;
using Galaxium.Protocol.Gui;

using Anculus.Core;

namespace Galaxium.Protocol.Irc.GtkGui
{
	public class StartDirectCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcConversation conv = chatWidget.Conversation as IrcConversation;
				
				if (conv.ChatConnection != null && conv.ChatConnection.IsConnected)
					(MenuItem as MenuItem).Sensitive = false;
				else
					(MenuItem as MenuItem).Sensitive = true;
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcConversation conv = chatWidget.Conversation as IrcConversation;
				
				conv.ConnectDCC ();
			}
		}
	}
	
	public class StopDirectCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcConversation conv = chatWidget.Conversation as IrcConversation;
				
				if (conv.ChatConnection != null && conv.ChatConnection.IsConnected)
					(MenuItem as MenuItem).Sensitive = true;
				else
					(MenuItem as MenuItem).Sensitive = false;
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcConversation conv = chatWidget.Conversation as IrcConversation;
				
				conv.ChatConnection.Disconnect ();
			}
		}
	}
	
	public class ViewLogsCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null && chatWidget.Conversation != null)
			{
				ViewHistoryDialog dialog = new ViewHistoryDialog (chatWidget.Conversation, chatWidget);
				ResponseType response = (ResponseType)dialog.Run();
				
				if (response == ResponseType.Apply)
				{
					
				}
				
				dialog.Destroy ();
			}
		}
	}
	
	public class FindTextCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			
		}
		
		public override void Run ()
		{
			
		}
	}
	
	public class SendFileCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				if (!chatWidget.Conversation.IsPrivateConversation)
				{
					(MenuItem as ImageMenuItem).Sensitive = false;
				}
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcContact contact = chatWidget.Conversation.PrimaryContact as IrcContact;
				IrcSession session = chatWidget.Session as IrcSession;
				
				if (contact != null && contact.DisplayName != session.Account.DisplayName)
				{
					SendFileDialog dialog = new SendFileDialog (contact);
					
					// Here we would fill the dialog with the options we intend to use to send the file.
					
					ResponseType response = (ResponseType) dialog.Run ();
					
					if (response == ResponseType.Apply)
					{
						if (dialog.Filename != null && dialog.Filename.Length > 0)
						{
							(contact.Session as IrcSession).SendFile (contact, dialog.Filename);
						}
					}
					
					dialog.Destroy();
				}
			}
		}
	}
	
	public class JoinConversationCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcSession session = chatWidget.Session as IrcSession;
				IrcChannel channel = session.ObtainChannel (chatWidget.Conversation.PrimaryContact.DisplayName, true);
				
				(MenuItem as MenuItem).Sensitive = channel.Presence == IrcPresence.Offline;
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcSession session = (chatWidget.Session as IrcSession);
				session.JoinChannel (chatWidget.Conversation.PrimaryContact.DisplayName, (chatWidget.Conversation.PrimaryContact as IrcChannel).Key, true, false);
			}
		}
	}
	
	public class PartConversationCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcSession session = chatWidget.Session as IrcSession;
				IrcChannel channel = session.ObtainChannel (chatWidget.Conversation.PrimaryContact.DisplayName, true);
				(MenuItem as MenuItem).Sensitive = channel.Presence == IrcPresence.Online;
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcSession session = (chatWidget.Session as IrcSession);
				session.PartChannels (chatWidget.Conversation.PrimaryContact.DisplayName);
			}
		}
	}
	
	public class CloseConversationCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
				chatWidget.Close();
		}
	}
	
	public class CloseWindowCommand: AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
		}
		
		public override void Run ()
		{
			var chat_widget = Object as IrcChatWidget;
			
			if (chat_widget != null)
				chat_widget.ContainerWindow.Close(false);
		}
	}
	
	public class ShowActionToolbarCommand : ConversationMenuCommand
	{
		public override void SetDefaultMenuItem ()
		{
			(MenuItem as CheckMenuItem).Active = UsingDefaultView ? _config.GetBool (Configuration.Conversation.ShowActivityToolbar.Name, Configuration.Conversation.ShowActivityToolbar.Default) : _chat_widget.ShowActionToolbar;
		}
		
		public override void RunDefault ()
		{
			if (UsingDefaultView)
			{
				Log.Debug ("using default");
				_config.SetBool (Configuration.Conversation.ShowActivityToolbar.Name, (MenuItem as CheckMenuItem).Active);
			}
			else
			{
				Log.Debug ("not using default");
				_chat_widget.ShowActionToolbar = (MenuItem as CheckMenuItem).Active;
				_chat_widget.Conversation.PrimaryContact.Save ();
			}
			
			_chat_widget.Update ();
		}
	}
	
	public class ShowInputToolbarCommand : ConversationMenuCommand
	{
		public override void SetDefaultMenuItem ()
		{
			(MenuItem as CheckMenuItem).Active = UsingDefaultView ? _config.GetBool (Configuration.Conversation.ShowInputToolbar.Name, Configuration.Conversation.ShowInputToolbar.Default) : _chat_widget.ShowInputToolbar;
		}
		
		public override void RunDefault ()
		{
			if (UsingDefaultView)
				_config.SetBool (Configuration.Conversation.ShowInputToolbar.Name, (MenuItem as CheckMenuItem).Active);
			else
			{
				_chat_widget.ShowInputToolbar = (MenuItem as CheckMenuItem).Active;
				_chat_widget.Conversation.PrimaryContact.Save ();
			}
			
			_chat_widget.Update ();
		}
	}
	
	public class UseDefaultViewCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
				(MenuItem as CheckMenuItem).Active = chatWidget.UseDefaultView;
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				chatWidget.UseDefaultView = (MenuItem as CheckMenuItem).Active;
				chatWidget.Conversation.PrimaryContact.Save ();
				chatWidget.SwitchTo ();
				chatWidget.Update ();
			}
		}
	}
	
	public class EnableLoggingCommand : ConversationMenuCommand
	{
		public override void SetDefaultMenuItem ()
		{
			(MenuItem as CheckMenuItem).Active = UsingDefaultSettings ? _config.GetBool (Configuration.Conversation.EnableLogging.Name, Configuration.Conversation.EnableLogging.Default) : _chat_widget.Conversation.EnableLogging;
		}
		
		public override void RunDefault ()
		{
			if (UsingDefaultSettings)
			{
				_config.SetBool (Configuration.Conversation.EnableLogging.Name, (MenuItem as CheckMenuItem).Active);
				_chat_widget.Conversation.EnableLogging = (MenuItem as CheckMenuItem).Active;
			}
			else
			{
				_chat_widget.Conversation.EnableLogging = (MenuItem as CheckMenuItem).Active;
				_chat_widget.Conversation.PrimaryContact.Save ();
			}
			
			_chat_widget.Update ();
		}
	}
	
	public class EnableSoundsCommand : ConversationMenuCommand
	{
		public override void SetDefaultMenuItem ()
		{
			(MenuItem as CheckMenuItem).Active = UsingDefaultSettings ? _config.GetBool (Configuration.Conversation.EnableSounds.Name, Configuration.Conversation.EnableSounds.Default) : _chat_widget.EnableSounds;
		}
		
		public override void RunDefault ()
		{
			if (UsingDefaultSettings)
				_config.SetBool (Configuration.Conversation.EnableSounds.Name, (MenuItem as CheckMenuItem).Active);
			else
			{
				_chat_widget.EnableSounds = (MenuItem as CheckMenuItem).Active;
				_chat_widget.Conversation.PrimaryContact.Save ();
			}
			
			_chat_widget.Update ();
		}
	}
	
	public class UseDefaultSettingsCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
				(MenuItem as CheckMenuItem).Active = chatWidget.Conversation.UseDefaultSettings;
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				chatWidget.Conversation.UseDefaultSettings = (MenuItem as CheckMenuItem).Active;
				chatWidget.Conversation.PrimaryContact.Save ();
				chatWidget.SwitchTo ();
				chatWidget.Update ();
			//	chatWidget.ReportLogging ();  FIXME
			}
		}
	}
	
	public class AutoJoinChannelCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcSession session = chatWidget.Session as IrcSession;
				IrcChannel channel = session.ObtainChannel (chatWidget.Conversation.PrimaryContact.DisplayName, true);
				(MenuItem as CheckMenuItem).Active = channel.AutoJoin;
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcSession session = chatWidget.Session as IrcSession;
				IrcChannel channel = session.ObtainChannel (chatWidget.Conversation.PrimaryContact.DisplayName, true);
				//IrcAccount account = channel.Session.Account as IrcAccount;
				
				channel.AutoJoin = (MenuItem as CheckMenuItem).Active;
			}
		}
	}
	
	public class PersistentChannelCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcSession session = chatWidget.Session as IrcSession;
				IrcChannel channel = session.ObtainChannel (chatWidget.Conversation.PrimaryContact.DisplayName, true);
				(MenuItem as CheckMenuItem).Active = channel.Persistent;
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null)
			{
				IrcSession session = chatWidget.Session as IrcSession;
				IrcChannel channel = session.ObtainChannel (chatWidget.Conversation.PrimaryContact.DisplayName, true);
				//IrcAccount account = channel.Session.Account as IrcAccount;
				
				channel.Persistent = (MenuItem as CheckMenuItem).Active;
			}
		}
	}
	
	public class ChangeModesCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null && chatWidget.Conversation != null && chatWidget.Session != null)
			{
				if (chatWidget.Conversation.ContactCollection != null && chatWidget.Session.Account != null)
				{
					IrcChannel channel = chatWidget.Conversation.PrimaryContact as IrcChannel;
					IrcContact contact = channel.ContactCollection.GetContactByName (chatWidget.Session.Account.DisplayName) as IrcContact;
					
					if (contact != null)
					{
						if (contact.HasChannelUserModes (ChannelModeFlags.Operator))
							(MenuItem as MenuItem).Sensitive = true;
						else
							(MenuItem as MenuItem).Sensitive = false;
					}
					else
						(MenuItem as MenuItem).Sensitive = false;
				}
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null && chatWidget.Conversation != null && chatWidget.Session != null)
			{
				IrcChannel channel = chatWidget.Conversation.PrimaryContact as IrcChannel;
				IrcSession session = chatWidget.Session as IrcSession;
				
				ChangeChannelModeDialog dialog = new ChangeChannelModeDialog (session, channel);
				ResponseType response = (ResponseType)dialog.Run ();
				 
				if (response == ResponseType.Apply)
				{
					ChannelModeFlags toAdd = ChannelModeFlags.None;
					ChannelModeFlags toRemove = ChannelModeFlags.None;
					
					if (channel.HasChannelModes (ChannelModeFlags.Moderated) != dialog.Moderated)
					{
						if (channel.HasChannelModes (ChannelModeFlags.Moderated))
							toRemove |= ChannelModeFlags.Moderated;
						else
							toAdd |= ChannelModeFlags.Moderated;
					}
					
					if (channel.HasChannelModes (ChannelModeFlags.PrivateChannel) != dialog.Private)
					{
						if (channel.HasChannelModes (ChannelModeFlags.PrivateChannel))
							toRemove |= ChannelModeFlags.PrivateChannel;
						else
							toAdd |= ChannelModeFlags.PrivateChannel;
					}
					
					if (channel.HasChannelModes (ChannelModeFlags.SecretChannel) != dialog.Secret)
					{
						if (channel.HasChannelModes (ChannelModeFlags.SecretChannel))
							toRemove |= ChannelModeFlags.SecretChannel;
						else
							toAdd |= ChannelModeFlags.SecretChannel;
					}
					
					if (channel.HasChannelModes (ChannelModeFlags.NoExternalMessages) != dialog.InternalOnly)
					{
						if (channel.HasChannelModes (ChannelModeFlags.NoExternalMessages))
							toRemove |= ChannelModeFlags.NoExternalMessages;
						else
							toAdd |= ChannelModeFlags.NoExternalMessages;
					}
					
					if (channel.HasChannelModes (ChannelModeFlags.InviteOnlyChannel) != dialog.InviteOnly)
					{
						if (channel.HasChannelModes (ChannelModeFlags.InviteOnlyChannel))
							toRemove |= ChannelModeFlags.InviteOnlyChannel;
						else
							toAdd |= ChannelModeFlags.InviteOnlyChannel;
					}
					
					if (channel.HasChannelModes (ChannelModeFlags.OnlyOperChangeTopic) != dialog.RestrictTopic)
					{
						if (channel.HasChannelModes (ChannelModeFlags.OnlyOperChangeTopic))
							toRemove |= ChannelModeFlags.OnlyOperChangeTopic;
						else
							toAdd |= ChannelModeFlags.OnlyOperChangeTopic;
					}
					
					string strAdd = IrcProtocolHelper.GetChannelModeString(toAdd);
					string strRemove = IrcProtocolHelper.GetChannelModeString(toRemove);
					
					if (strAdd.Length > 0)
						session.ChangeMode (channel.DisplayName, "+"+strAdd, null);
					
					if (strRemove.Length > 0)
						session.ChangeMode (channel.DisplayName, "-"+strRemove, null);
				}
				
				dialog.Destroy ();
			}
		}
	}
	
	public class ChangeBansCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null && chatWidget.Conversation != null && chatWidget.Session != null)
			{
				if (chatWidget.Conversation.ContactCollection != null && chatWidget.Session.Account != null)
				{
					IrcContact contact = chatWidget.Conversation.ContactCollection.GetContactByName (chatWidget.Session.Account.DisplayName) as IrcContact;
					if (contact != null)
					{
						if (contact.HasChannelUserModes (ChannelModeFlags.Operator))
							(MenuItem as MenuItem).Sensitive = true;
						else
							(MenuItem as MenuItem).Sensitive = false;
					}
				}
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null && chatWidget.Conversation != null && chatWidget.Session != null)
			{
				IrcChannel channel = chatWidget.Conversation.PrimaryContact as IrcChannel;
				IrcSession session = chatWidget.Session as IrcSession;
				
				ChangeBansDialog dialog = new ChangeBansDialog (session, channel);
				ResponseType response = (ResponseType)dialog.Run ();
				 
				if (response == ResponseType.Apply)
				{
					
				}
				
				dialog.Destroy ();
			}
		}
	}
	
	public class ChangeTopicCommand : AbstractMenuCommand
	{
		public override void SetMenuItem ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null && chatWidget.Conversation != null && chatWidget.Session != null)
			{
				if (chatWidget.Conversation.ContactCollection != null && chatWidget.Session.Account != null)
				{
					IrcContact contact = chatWidget.Conversation.ContactCollection.GetContactByName (chatWidget.Session.Account.DisplayName) as IrcContact;
					if (contact != null)
					{
						if (contact.HasChannelUserModes (ChannelModeFlags.Operator))
							(MenuItem as MenuItem).Sensitive = true;
						else
							(MenuItem as MenuItem).Sensitive = false;
					}
				}
			}
		}
		
		public override void Run ()
		{
			IrcChatWidget chatWidget = Object as IrcChatWidget;
			
			if (chatWidget != null && chatWidget.Conversation != null && chatWidget.Session != null)
			{
				IrcChannel channel = chatWidget.Conversation.PrimaryContact as IrcChannel;
				IrcSession session = chatWidget.Session as IrcSession;
				
				ChangeTopicDialog dialog = new ChangeTopicDialog (session, channel);
				ResponseType response = (ResponseType)dialog.Run ();
				 
				if (response == ResponseType.Apply)
				{
					session.ChangeTopic (channel.DisplayName, dialog.Topic);
				}
				else if (response == ResponseType.No)
				{
					session.ChangeTopic (channel.DisplayName, string.Empty);
				}
				
				dialog.Destroy ();
			}
		}
	}
}
